home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Development / General / Open Prolog / External Predicates… / Sources / prlxLibraries.p < prev    next >
Text File  |  1993-11-30  |  24KB  |  823 lines

  1. {$D+} { MacsBug symbols on }
  2. {$R-} { No range checking }
  3.  
  4. UNIT prlxLibraries;
  5.  
  6.   INTERFACE
  7.  
  8.     USES memtypes, quickdraw, osintf, toolintf,traps,StandardFile,TextUtils, prlxdefinitions;
  9.     
  10.     TYPE
  11.  
  12.       oeAction = (oeDoNothing, oeCloseFile, oeCloseResFile, oeDeleteFile,
  13.                   oeDisposHandle, oeDisposPtr);
  14.       oeRecHdl = ^oeRecPtr;
  15.       oeRecPtr = ^oeRec;
  16.       oeRec = RECORD
  17.                 action: oeAction;
  18.                 parameter: longint;
  19.                 next: oeRecHdl;
  20.               END;
  21.  
  22.     PROCEDURE addOE(VAR list: oeRecHdl;
  23.                     action: oeAction;
  24.                     parameter: longint);
  25.  
  26.  
  27.     FUNCTION removeOE(VAR list: oeRecHdl;
  28.                       action: oeAction;
  29.                       parameter: longint): osErr;
  30.  
  31.     FUNCTION doOE(VAR list: oeRecHdl): osErr;
  32.  
  33.  
  34.     PROCEDURE initOE(VAR list: oeRecHdl);
  35.  
  36.     FUNCTION terminateOE(VAR list: oeRecHdl): osErr;
  37.  
  38.     FUNCTION TrapAvailable(tNumber: integer; tType: TrapType): boolean;
  39.  
  40.     FUNCTION getStringNumber(id, index: integer): longint;
  41.  
  42.  
  43.     FUNCTION walkAList(list: termIndex;
  44.                        VAR head, tail: termIndex;
  45.                        plist: prlxptr): boolean;
  46.  
  47.     FUNCTION textOfAtomicList(termnumber: termindex;
  48.                               plist: prlxPtr): str255;
  49.  
  50.     FUNCTION returnString(termNumber: termIndex;
  51.                           st: str255;
  52.                           plist: prlxPtr): boolean;
  53.     
  54.     PROCEDURE openPrologDialogFilter(VAR i: integer; plist:prlxPtr);
  55.  
  56.     PROCEDURE writestr(st: str255; plist: prlxPtr);
  57.  
  58.     PROCEDURE writelnstr(st: str255; plist: prlxPtr);
  59.  
  60.     PROCEDURE errorstr(st: str255; plist: prlxPtr);
  61.  
  62.     FUNCTION returnValue(termNumber: termIndex; n: longint;
  63.                          plist: prlxPtr): boolean;
  64.  
  65.     FUNCTION returnStructure(termNumber: termIndex; st: str255; arity: integer;
  66.                              plist: prlxPtr): boolean;
  67.  
  68.     FUNCTION returnList(termNumber: termIndex; plist: prlxPtr): boolean;
  69.  
  70.     FUNCTION returnAtom(termNumber: termIndex; st: str255;
  71.                         plist: prlxPtr): boolean;
  72.  
  73.     FUNCTION returnUnifiedTerms(a, b: termIndex; plist: prlxPtr): boolean;
  74.  
  75.     FUNCTION subterm(subtermordinate: integer; termNumber: termIndex;
  76.                      plist: prlxPtr): termIndex;
  77.  
  78.     FUNCTION newFreeTerm(plist: prlxPtr): termIndex;
  79.  
  80.     FUNCTION number(termNumber: termIndex; plist: prlxPtr): boolean;
  81.  
  82.     FUNCTION atom(termNumber: termIndex; plist: prlxPtr): boolean;
  83.  
  84.     FUNCTION structure(termNumber: termIndex; plist: prlxPtr): boolean;
  85.  
  86.     FUNCTION list(termNumber: termIndex; plist: prlxPtr): boolean;
  87.  
  88.     FUNCTION variable(termNumber: termIndex; plist: prlxPtr): boolean;
  89.  
  90.     FUNCTION value(termNumber: termIndex; plist: prlxPtr): longint;
  91.  
  92.     FUNCTION arity(termNumber: termIndex; plist: prlxPtr): integer;
  93.  
  94.     FUNCTION text(termNumber: termIndex; plist: prlxPtr): str255;
  95.  
  96.     FUNCTION drawAlert(ALRTid: integer; st: str255; plist: prlxPtr): longint;
  97.  
  98.     FUNCTION centreDialog(DLOGid: integer; plist: prlxPtr): longint;
  99.  
  100.     PROCEDURE centreSfGetTEXTFile(vertical: integer; str: str255;
  101.                                   VAR reply: sfReply);
  102.  
  103.     PROCEDURE centreSfPutFile(vertical: integer; str: str255; origName: str255;
  104.                               dlgHook: procPtr; VAR reply: sfReply);
  105.  
  106.     FUNCTION getFileName(VAR FileName: str255;
  107.                          VAR FileVolume: longint): boolean;
  108.  
  109.     FUNCTION predicateNameAndArity(VAR name: str255; VAR arity: integer;
  110.                                    plist: prlxPtr): boolean;
  111.  
  112.     PROCEDURE signalError(error: integer; argumentIndex: integer;
  113.                           hostErrorCode: longint; errorMessage: str255;
  114.                           plist: prlxPtr);
  115.  
  116.   IMPLEMENTATION
  117.  
  118.     PROCEDURE signalError(error: integer; argumentIndex: integer;
  119.                           hostErrorCode: longint; errorMessage: str255;
  120.                           plist: prlxPtr);
  121.  
  122.     {if you want to throw an error from an external predicate, use this}
  123.     {error kind is an index to an ISO error type - see prlxDefinitions.p}
  124.     {hostErrorCode is where you can put a mac error code}
  125.     {give an argument index of -1 if you don't want it to try to output the goal's name}
  126.  
  127.       VAR
  128.         i: integer;
  129.         t, r, q: termIndex;
  130.         ignoreBoolean: boolean;
  131.         thePredicateName: str255;
  132.         thePredicateArity: integer;
  133.  
  134.       BEGIN
  135.  
  136.         WITH plist^ DO
  137.           BEGIN
  138.           outcome := error; {outcome is normally 'notAnErrorCode' - this puts a
  139.                              real error code there}
  140.           data[1] := newFreeTerm(plist);
  141.           END;
  142.         ignoreBoolean := predicateNameAndArity(thePredicateName,
  143.                                                thePredicateArity, plist);
  144.  
  145.         q := plist^.data[1];
  146.  
  147.         IF argumentIndex <> - 1 {-1 is flag to not even try to output the goal's name}
  148.           THEN
  149.             BEGIN
  150.             ignoreBoolean := returnList(q, plist); {return a list of error
  151.                                                     information}
  152.             r := subterm(1, q, plist);
  153.             ignoreBoolean := returnStructure(r, 'goal', 1, plist); {first, the
  154.               goal - functor & arguments}
  155.             r := subterm(1, r, plist);
  156.             ignoreBoolean := returnStructure(r, thePredicateName,
  157.                                              thePredicateArity, plist);
  158.             FOR i := 1 TO thePredicateArity DO
  159.               ignoreBoolean := returnUnifiedTerms(subterm(i, r, plist), i,
  160.                                                   plist); {the goal's
  161.                                                             arguments}
  162.             q := subterm(2, q, plist);
  163.             END;
  164.  
  165.         IF argumentIndex > 0 {if the argument index is 0 or -1, no argument
  166.                               index info returned}
  167.           THEN
  168.             BEGIN
  169.             ignoreBoolean := returnList(q, plist);
  170.             r := subterm(1, q, plist);
  171.             ignoreBoolean := returnStructure(r, 'argument_index', 1, plist);
  172.             r := subterm(1, r, plist);
  173.             ignoreBoolean := returnValue(r, argumentIndex, plist);
  174.             q := subterm(2, q, plist);
  175.             END;
  176.  
  177.         IF hostErrorCode <> 0 {if the mac error code = 0, no host error info
  178.                                returned}
  179.           THEN
  180.             BEGIN
  181.             ignoreBoolean := returnList(q, plist);
  182.             r := subterm(1, q, plist);
  183.             ignoreBoolean := returnStructure(r, 'host_error_code', 1, plist);
  184.             r := subterm(1, r, plist);
  185.             ignoreBoolean := returnValue(r, hostErrorCode, plist);
  186.             q := subterm(2, q, plist);
  187.             END;
  188.  
  189.         IF errorMessage <> '' {only return an error message term if it's
  190.                                non-blank}
  191.           THEN
  192.             BEGIN
  193.             ignoreBoolean := returnList(q, plist);
  194.             r := subterm(1, q, plist);
  195.             ignoreBoolean := returnStructure(r, 'error_message', 1, plist);
  196.             r := subterm(1, r, plist);
  197.             ignoreBoolean := returnAtom(r, errorMessage, plist);
  198.             q := subterm(2, q, plist);
  199.             END;
  200.  
  201.         ignoreBoolean := returnAtom(q, '[]', plist); {terminate the list}
  202.       END;
  203.  
  204.     PROCEDURE addOE(VAR list: oeRecHdl;
  205.                     action: oeAction;
  206.                     parameter: longint);
  207.  
  208.       VAR
  209.         temp: oeRecHdl;
  210.  
  211.       BEGIN
  212.         temp := oeRecHdl(newHandleClear(sizeOf(oeRec)));
  213.         temp^^.next := list;
  214.         list := temp;
  215.         list^^.action := action;
  216.         list^^.parameter := parameter;
  217.       END;
  218.  
  219.     FUNCTION existsOE(VAR list: oeRecHdl;
  220.                       action: oeAction;
  221.                       VAR parameter: longint): boolean;
  222.  
  223.       VAR
  224.         temp: oeRecHdl;
  225.         found: boolean;
  226.  
  227.       BEGIN
  228.         temp := list;
  229.         found := false;
  230.         REPEAT
  231.           IF temp <> NIL THEN
  232.             BEGIN
  233.             IF temp^^.action = action THEN
  234.               found := true
  235.             ELSE
  236.               temp := temp^^.next;
  237.             END;
  238.         UNTIL (temp = NIL) OR found;
  239.         IF found THEN parameter := temp^^.parameter;
  240.         existsOE := found;
  241.       END;
  242.  
  243.     FUNCTION removeOE(VAR list: oeRecHdl;
  244.                       action: oeAction;
  245.                       parameter: longint): osErr;
  246.  
  247.       VAR
  248.         temp: oeRecHdl;
  249.         found: boolean;
  250.  
  251.       BEGIN
  252.         temp := list;
  253.         REPEAT
  254.           IF temp <> NIL THEN
  255.             BEGIN
  256.             found := (temp^^.action = action) AND (temp^^.parameter =
  257.                      parameter);
  258.             IF NOT found THEN temp := temp^^.next;
  259.             END;
  260.         UNTIL (temp = NIL) OR found;
  261.         IF found THEN
  262.           BEGIN
  263.           removeOE := noErr;
  264.           temp^^.action := oeDoNothing;
  265.           END
  266.         ELSE
  267.           removeOE := paramErr;
  268.       END;
  269.  
  270.     FUNCTION doOE(VAR list: oeRecHdl): osErr;
  271.  
  272.       TYPE
  273.         fssSpecPtr = ^fsSpec;
  274.  
  275.       VAR
  276.         temp: oeRecHdl;
  277.         thePort: grafPtr;
  278.         errorCode: osErr;
  279.  
  280.       BEGIN
  281.         errorCode := noErr;
  282.         WHILE (list <> NIL) AND (errorCode = noErr) DO
  283.           WITH list^^ DO
  284.             BEGIN
  285.             hLock(handle(list));
  286.             CASE action OF
  287.               oeDoNothing: ;
  288.               oeCloseFile: errorCode := fsClose(parameter);
  289.               oeCloseResFile:
  290.                 BEGIN
  291.                 closeResFile(parameter);
  292.                 errorCode := resError;
  293.                 END;
  294.               oeDeleteFile: errorCode := fSpDelete(fssSpecPtr(parameter)^);
  295.               oeDisposHandle:
  296.                 BEGIN
  297.                 disposHandle(handle(parameter));
  298.                 errorCode := memError;
  299.                 END;
  300.               oeDisposPtr:
  301.                 BEGIN
  302.                 disposPtr(ptr(parameter));
  303.                 errorCode := memError;
  304.                 END;
  305.             END;
  306.             IF errorCode = noErr THEN
  307.               BEGIN
  308.               temp := list^^.next;
  309.               disposHandle(handle(list));
  310.               list := temp;
  311.               END;
  312.             END;
  313.       END;
  314.  
  315.     PROCEDURE initOE(VAR list: oeRecHdl);
  316.  
  317.       BEGIN
  318.         list := NIL;
  319.       END;
  320.  
  321.     FUNCTION terminateOE(VAR list: oeRecHdl): osErr;
  322.  
  323.       VAR
  324.         temp: oeRecHdl;
  325.         result: osErr;
  326.  
  327.       BEGIN
  328.         result := 0;
  329.         WHILE list <> NIL DO
  330.           BEGIN
  331.           IF list^^.action <> oeDoNothing THEN result := paramErr;
  332.           temp := list;
  333.           list := list^^.next;
  334.           disposHandle(handle(temp));
  335.           END;
  336.         terminateOE := result;
  337.       END;
  338.  
  339.       PROCEDURE openPrologDialogFilter(VAR i: integer; plist:prlxPtr);
  340.  
  341.         VAR
  342.           l: longint;
  343.  
  344.         BEGIN
  345.           WITH plist^ DO
  346.             BEGIN
  347.             callbackrequest := doMyModalDialog;
  348.             callback(entrypoint);
  349.             l := callbackdata[1];
  350.             i := l;
  351.             END;
  352.         END;
  353.  
  354.     FUNCTION TrapAvailable(tNumber: integer; tType: TrapType): boolean;
  355.  
  356. {Check to see if a given trap is implemented.
  357.  The recommended approach to see if a trap is implemented is to see if
  358.  the address of the trap routine is the same as the address of the
  359.  Unimplemented trap.}
  360.  
  361.       VAR
  362.         gMac: sysEnvRec;
  363.         errCode: osErr;
  364.  
  365.       BEGIN
  366.         errCode := noErr;
  367.         IF (tType = ToolTrap)
  368.           THEN
  369.             BEGIN
  370.             errCode := sysEnvirons(1, gMac);
  371.             IF (errCode = noErr) & (gMac.machineType > envMachUnknown) &
  372.                (gMac.machineType < envMacII)
  373.               THEN
  374.                 BEGIN {it's a 512KE, Plus, or SE}
  375.                 tNumber := BAND(tNumber, $03FF);
  376.                 IF tNumber > $01FF
  377.                   THEN {which means the tool traps}
  378.                     tNumber := _Unimplemented; {only go to $01FF}
  379.                 END;
  380.             END;
  381.         TrapAvailable := (NGetTrapAddress(tNumber, tType) <>
  382.                          GetTrapAddress(_Unimplemented)) AND (errCode = noErr);
  383.       END; {TrapAvailable}
  384.  
  385.     FUNCTION getStringNumber(id, index: integer): longint;
  386.  
  387.       VAR
  388.         s: Str255;
  389.         n: longint;
  390.         i: integer;
  391.  
  392.       BEGIN
  393.         getIndString(s, id, index);
  394.         i := 1;
  395.         n := 0;
  396.         IF length(s) <> 0 THEN
  397.           WHILE (i <= length(s)) AND (s[i] IN ['0'..'9']) DO
  398.             BEGIN
  399.             n := n * 10 + ord(s[i]) - ord('0');
  400.             i := i + 1;
  401.             END;
  402.         getStringNumber := n;
  403.       END;
  404.  
  405.     FUNCTION walkAList(list: termIndex;
  406.                        VAR head, tail: termIndex;
  407.                        plist: prlxptr): boolean;
  408.  
  409.       BEGIN
  410.         IF (text(list, plist) = '.') AND (arity(list, plist) = 2) THEN
  411.           BEGIN
  412.           walkAList := true;
  413.           head := subTerm(1, list, plist);
  414.           tail := subTerm(2, list, plist);
  415.           END
  416.         ELSE
  417.           walkAList := false;
  418.       END;
  419.  
  420.     FUNCTION textOfAtomicList(termnumber: termindex;
  421.                               plist: prlxPtr): str255;
  422.  
  423.       VAR
  424.         st: str255;
  425.         i: integer;
  426.  
  427.       BEGIN
  428.         IF (text(termNumber, plist) <> '.') OR (arity(termNumber, plist) <>
  429.            2) THEN
  430.           textOfAtomicList := text(termNumber, plist)
  431.         ELSE
  432.           BEGIN
  433.           st := '';
  434.           WHILE (text(termNumber, plist) = '.') AND (arity(termNumber, plist) =
  435.                 2) DO
  436.             BEGIN
  437.             st := concat(st, char(value(subterm(1, termNumber, plist), plist)));
  438.             termNumber := subterm(2, termNumber, plist);
  439.             END;
  440.           textOfAtomicList := st;
  441.           END;
  442.       END;
  443.  
  444.     FUNCTION returnString(termNumber: termIndex;
  445.                           st: str255;
  446.                           plist: prlxPtr): boolean;
  447.  
  448.       VAR
  449.         continue: boolean;
  450.         i: integer;
  451.         runningTerm: termIndex;
  452.  
  453.       BEGIN
  454.         runningTerm := termNumber;
  455.         continue := true;
  456.         IF st <> '' THEN
  457.           FOR i := 1 TO length(st) DO
  458.             BEGIN
  459.             IF continue THEN
  460.               continue := returnStructure(runningTerm, '.', 2, plist);
  461.             IF continue THEN
  462.               continue := returnValue(subterm(1, runningTerm, plist),
  463.                                       ord(st[i]), plist);
  464.             IF continue THEN runningTerm := subterm(2, runningTerm, plist);
  465.             END;
  466.         IF continue THEN continue := returnAtom(runningTerm, '[]', plist);
  467.         returnString := continue;
  468.       END;
  469.  
  470.     PROCEDURE writestr(st: str255; plist: prlxPtr);
  471.  
  472.       BEGIN
  473.         WITH plist^ DO
  474.           BEGIN
  475.           callbackrequest := writestring;
  476.           s := st;
  477.           callback(entrypoint);
  478.           END;
  479.       END;
  480.  
  481.     PROCEDURE writelnstr(st: str255; plist: prlxPtr);
  482.  
  483.       BEGIN
  484.         WITH plist^ DO
  485.           BEGIN
  486.           callbackrequest := writelnstring;
  487.           s := st;
  488.           callback(entrypoint);
  489.           END;
  490.       END;
  491.  
  492.     PROCEDURE errorstr(st: str255; plist: prlxPtr);
  493.  
  494.       BEGIN
  495.         WITH plist^ DO
  496.           BEGIN
  497.           callbackrequest := writeerror;
  498.           s := st;
  499.           callback(entrypoint);
  500.           END;
  501.       END;
  502.  
  503.     FUNCTION predicateNameAndArity(VAR name: str255; VAR arity: integer;
  504.                                    plist: prlxPtr): boolean;
  505.  
  506.       BEGIN
  507.         WITH plist^ DO
  508.           BEGIN
  509.           callbackrequest := getPredicateNameAndArity;
  510.           callback(entrypoint);
  511.           predicateNameAndArity := callbackData[3] = messageOK;
  512.           name := s;
  513.           arity := callbackData[1];
  514.           END;
  515.       END;
  516.  
  517.     FUNCTION returnUnifiedTerms(a, b: termIndex; plist: prlxPtr): boolean;
  518.  
  519.       BEGIN
  520.         WITH plist^ DO
  521.           BEGIN
  522.           callbackrequest := unifyTerms;
  523.           callbackData[1] := a;
  524.           callbackData[2] := b;
  525.           callback(entrypoint);
  526.           returnUnifiedTerms := callbackData[3] = messageOK;
  527.           END;
  528.       END;
  529.  
  530.     FUNCTION returnValue(termNumber: termIndex; n: longint;
  531.                          plist: prlxPtr): boolean;
  532.  
  533.       BEGIN
  534.         WITH plist^ DO
  535.           BEGIN
  536.           callbackrequest := unifyToInteger;
  537.           callbackData[1] := termNumber;
  538.           callbackData[2] := n;
  539.           callback(entrypoint);
  540.           returnValue := callbackData[3] = messageOK;
  541.           END;
  542.       END;
  543.  
  544.     FUNCTION returnList(termNumber: termIndex; plist: prlxPtr): boolean;
  545.  
  546.       BEGIN
  547.         WITH plist^ DO
  548.           BEGIN
  549.           callbackrequest := unifyToFunctor;
  550.           callbackData[1] := termNumber;
  551.           callbackData[3] := 2;
  552.           s := '.';
  553.           callback(entrypoint);
  554.           returnList := callbackData[3] = messageOK;
  555.           END;
  556.       END;
  557.  
  558.     FUNCTION returnStructure(termNumber: termIndex; st: str255; arity: integer;
  559.                              plist: prlxPtr): boolean;
  560.  
  561.       BEGIN
  562.         WITH plist^ DO
  563.           BEGIN
  564.           callbackrequest := unifyToFunctor;
  565.           callbackData[1] := termNumber;
  566.           callbackData[3] := arity;
  567.           s := st;
  568.           callback(entrypoint);
  569.           returnStructure := callbackData[3] = messageOK;
  570.           END;
  571.       END;
  572.  
  573.     FUNCTION returnAtom(termNumber: termIndex; st: str255;
  574.                         plist: prlxPtr): boolean;
  575.  
  576.       BEGIN
  577.         returnAtom := returnStructure(termNumber, st, 0, plist);
  578.       END;
  579.  
  580.     FUNCTION subterm(subtermordinate: integer; termNumber: termIndex;
  581.                      plist: prlxPtr): termIndex;
  582.  
  583.       BEGIN
  584.         WITH plist^ DO
  585.           BEGIN
  586.           callbackrequest := getsubterm;
  587.           callbackData[1] := termNumber;
  588.           callbackData[2] := subtermordinate;
  589.           callback(entrypoint);
  590.           subterm := callbackData[3];
  591.           END;
  592.       END;
  593.  
  594.     FUNCTION newFreeTerm(plist: prlxPtr): termIndex;
  595.  
  596.       BEGIN
  597.         WITH plist^ DO
  598.           BEGIN
  599.           callbackrequest := getFreeTerm;
  600.           callback(entrypoint);
  601.           newFreeTerm := callbackData[1];
  602.           END;
  603.       END;
  604.  
  605.     FUNCTION number(termNumber: termIndex; plist: prlxPtr): boolean;
  606.  
  607.       BEGIN
  608.         WITH plist^ DO
  609.           BEGIN
  610.           callbackrequest := getterminfo;
  611.           callbackData[1] := termNumber;
  612.           callback(entrypoint);
  613.           number := (callbackData[1] = integertag);
  614.           END;
  615.       END;
  616.  
  617.     FUNCTION atom(termNumber: termIndex; plist: prlxPtr): boolean;
  618.  
  619.       BEGIN
  620.         WITH plist^ DO
  621.           BEGIN
  622.           callbackrequest := getterminfo;
  623.           callbackData[1] := termNumber;
  624.           callback(entrypoint);
  625.           atom := (callbackData[1] = atomtag);
  626.           END;
  627.       END;
  628.  
  629.     FUNCTION structure(termNumber: termIndex; plist: prlxPtr): boolean;
  630.  
  631.       BEGIN
  632.         WITH plist^ DO
  633.           BEGIN
  634.           callbackrequest := getterminfo;
  635.           callbackData[1] := termNumber;
  636.           callback(entrypoint);
  637.           structure := (callbackData[1] = structuretag);
  638.           END;
  639.       END;
  640.  
  641.     FUNCTION list(termNumber: termIndex; plist: prlxPtr): boolean;
  642.  
  643.       BEGIN
  644.         WITH plist^ DO
  645.           BEGIN
  646.           callbackrequest := getterminfo;
  647.           callbackData[1] := termNumber;
  648.           callback(entrypoint);
  649.           list := ((callbackData[1] = structuretag) AND (s = '.') AND
  650.                   (callbackData[2] = 2)) OR ((callbackData[1] = atomtag) AND
  651.                   (s = '[]'));
  652.           END;
  653.       END;
  654.  
  655.     FUNCTION variable(termNumber: termIndex; plist: prlxPtr): boolean;
  656.  
  657.       BEGIN
  658.         WITH plist^ DO
  659.           BEGIN
  660.           callbackrequest := getterminfo;
  661.           callbackData[1] := termNumber;
  662.           callback(entrypoint);
  663.           variable := (callbackData[1] = variabletag);
  664.           END;
  665.       END;
  666.  
  667.     FUNCTION value(termNumber: termIndex; plist: prlxPtr): longint;
  668.  
  669.       BEGIN
  670.         WITH plist^ DO
  671.           BEGIN
  672.           callbackrequest := getterminfo;
  673.           callbackData[1] := termNumber;
  674.           callback(entrypoint);
  675.           IF callbackData[1] = integertag
  676.             THEN value := callbackData[2]
  677.             ELSE errorstr('attempt to get value of a non-integer', plist);
  678.           END;
  679.       END;
  680.  
  681.     FUNCTION arity(termNumber: termIndex; plist: prlxPtr): integer;
  682.  
  683.       BEGIN
  684.         WITH plist^ DO
  685.           BEGIN
  686.           callbackrequest := getterminfo;
  687.           callbackData[1] := termNumber;
  688.           callback(entrypoint);
  689.           CASE callbackData[1] OF
  690.             atomtag, integertag, variabletag: arity := 0;
  691.             structuretag: arity := callbackData[2];
  692.             OTHERWISE errorstr('Funny data from getTermInfo in arity', plist);
  693.           END;
  694.           END;
  695.       END;
  696.  
  697.     FUNCTION text(termNumber: termIndex; plist: prlxPtr): str255;
  698.  
  699.       VAR
  700.         st: str255;
  701.         i: integer;
  702.  
  703.       BEGIN
  704.         WITH plist^ DO
  705.           BEGIN
  706.           callbackrequest := getterminfo;
  707.           callbackData[1] := termNumber;
  708.           callback(entrypoint);
  709.           CASE callbackData[1] OF
  710.             atomtag, structuretag: text := s;
  711.             integertag:
  712.               BEGIN
  713.               numtostring(callbackData[2], st);
  714.               text := st;
  715.               END;
  716.             variabletag:
  717.               BEGIN
  718.               numtostring(callbackData[2], st);
  719.               FOR i := 255 DOWNTO 2 DO st[i] := st[i - 1];
  720.               st[1] := '_';
  721.               text := st;
  722.               END;
  723.             OTHERWISE errorstr('Funny data from getTermInfo in text', plist);
  724.           END;
  725.           END;
  726.       END;
  727.  
  728.     FUNCTION drawAlert(ALRTid: integer; st: str255; plist: prlxPtr): longint;
  729.  
  730.       BEGIN
  731.         WITH plist^ DO
  732.           BEGIN
  733.           callbackrequest := drawALRT;
  734.           callbackData[1] := ALRTid;
  735.           s := st;
  736.           callback(entrypoint);
  737.           drawAlert := callbackData[2];
  738.           END;
  739.       END;
  740.  
  741.     FUNCTION centreDialog(DLOGid: integer; plist: prlxPtr): longint;
  742.  
  743.       VAR
  744.         item: integer;
  745.         myDialog: dialogPtr;
  746.  
  747.       BEGIN
  748.         WITH plist^ DO
  749.           BEGIN
  750.   (* ###hack        callbackrequest := drawDLOG;
  751.           callbackData[1] := DLOGid;
  752.            callback(entrypoint);
  753.           centreDialog := callbackData[2]; *)
  754.  
  755.           myDialog := getNewDialog(DLOGid, NIL, windowPtr(1));
  756.           showWindow(myDialog);
  757.           modalDialog(NIL, item);
  758.           disposDialog(myDialog);
  759.           centreDialog := item;
  760.           END;
  761.       END;
  762.  
  763.     PROCEDURE centreSfGetTEXTFile(vertical: integer; str: str255;
  764.                                   VAR reply: sfReply);
  765.  
  766.       VAR
  767.         myPoint: point;
  768.         dialogHandle: dialogTHndl;
  769.         myPort: grafPtr;
  770.         screenWidth, dialogWidth: integer;
  771.         myTypeList: sfTypeList;
  772.  
  773.       BEGIN
  774.         myTypeList[0] := 'TEXT';
  775.         getPort(myPort);
  776.         WITH myPort^.portBits.bounds DO screenWidth := right - left;
  777.         dialogHandle := dialogTHndl(getResource('DLOG', getDlgId));
  778.         WITH dialogHandle^^.boundsRect DO
  779.           BEGIN
  780.           dialogWidth := right - left;
  781.           myPoint.h := (screenWidth - dialogWidth) DIV 2;
  782.           myPoint.v := vertical;
  783.           END;
  784.         sfGetFile(myPoint, str, NIL, 1, myTypeList, NIL, reply);
  785.       END;
  786.  
  787.     PROCEDURE centreSfPutFile(vertical: integer; str: str255; origName: str255;
  788.                               dlgHook: procPtr; VAR reply: sfReply);
  789.  
  790.       VAR
  791.         myPoint: point;
  792.         dialogHandle: dialogTHndl;
  793.         myPort: grafPtr;
  794.         screenWidth, dialogWidth: integer;
  795.  
  796.       BEGIN
  797.         getPort(myPort);
  798.         WITH myPort^.portBits.bounds DO screenWidth := right - left;
  799.         dialogHandle := dialogTHndl(getResource('DLOG', putDlgId));
  800.         WITH dialogHandle^^.boundsRect DO
  801.           BEGIN
  802.           dialogWidth := right - left;
  803.           myPoint.h := (screenWidth - dialogWidth) DIV 2;
  804.           myPoint.v := vertical;
  805.           END;
  806.         sfPutFile(myPoint, str, origName, dlgHook, reply);
  807.       END;
  808.  
  809.     FUNCTION getFileName(VAR FileName: str255;
  810.                          VAR FileVolume: longint): boolean;
  811.  
  812.       VAR
  813.         reply: sfReply;
  814.  
  815.       BEGIN
  816.         centreSfGetTEXTFile(75, '', reply);
  817.         FileName := reply.fName;
  818.         FileVolume := reply.vRefNum;
  819.         getFileName := reply.good;
  820.       END;
  821.  
  822. END.
  823.